package com.nulldev.util.web.YouTubeExtractor.channel;

import java.util.ArrayList;
import java.util.List;

import com.nulldev.util.JVM.Arguments;
import com.nulldev.util.data.Variables;
import com.nulldev.util.internal.backport.concurrency9.Lists;
import com.nulldev.util.languages.json.uniapi.UniJsonValue;
import com.nulldev.util.logging.Logger;
import com.nulldev.util.logging.LoggerFactory;
import com.nulldev.util.web.YouTubeExtractor.channel.ChannelExtractor.Thumbnail;

final class ChannelUtil {

	private static final Logger log = LoggerFactory.getLoggerD(Arguments.hasArgument("--debug", "-debug", "--trace", "--ChannelUtil.debug"));

	static void __ENSURE_ARRAY(final UniJsonValue val) {
		if (!Variables.requireNonNullObject(val, "val").isArray())
			throw new RuntimeException("val is not an array!");
	}

	static final List<Thumbnail> makeBanners(final UniJsonValue header) {
		Variables.requireNonNull(header, "header");
		if (header.contains("banner")) {
			final UniJsonValue c4TabbedHeaderRenderer = header;
			final UniJsonValue banner = c4TabbedHeaderRenderer.get("banner");
			final UniJsonValue thumbnails = banner.get("thumbnails").asArray();
			return __do_banner_append(thumbnails);
		} else if (header.contains("pageHeaderViewModel")) {
			final UniJsonValue pageHeaderViewModel = header.get("pageHeaderViewModel");

			if (pageHeaderViewModel == null || pageHeaderViewModel.isNull()) {
				log.error("[makeBanners] Failed to find a pageHeaderViewModel object!");
				return Lists.of();
			}

			if (!pageHeaderViewModel.contains("banner")) {
				log.error("[makeBanners] Failed to find a banner in pageHeaderViewModel!");
				return Lists.of();
			}

			final UniJsonValue banner = pageHeaderViewModel.get("banner");
			final UniJsonValue thumbnails = banner.get("imageBannerViewModel").get("image").get("sources").asArray();
			return __do_banner_append(thumbnails);
		} else {
			log.warn("[makeBanners] No banners found, um.");
			log.dwarn(header);
			return Lists.of();
		}
	}

	private static List<Thumbnail> __do_banner_append(final UniJsonValue thumbnails) {
		if (thumbnails.size() == 0) {
			return Lists.of();
		}
		final List<Thumbnail> tb = new ArrayList<Thumbnail>();
		if (thumbnails.size() == 1) {
			final UniJsonValue obj = thumbnails.first();
			tb.add(new Thumbnail(obj.getInt("width"), obj.getInt("height"), obj.getString("url"), "YTE_FLAG_SINGLE"));
		} else {
			for (int idx = 0; idx < thumbnails.size(); idx++) {
				final UniJsonValue obj = thumbnails.get(idx);
				final String flag;
				/* I hope YouTube doesn't change the low -> high resolution ordering... */
				if (idx == 0) {
					flag = ChannelExtractor.MINIMUM_RESOLUTION_FLAG;
				} else if (idx == thumbnails.size() - 1) {
					flag = ChannelExtractor.MAXIMUM_RESOLUTION_FLAG;
				} else {
					flag = null;
				}
				tb.add(new Thumbnail(obj.getInt("width"), obj.getInt("height"), obj.getString("url"), flag));
			}
		}
		return tb;
	}

	static final List<Thumbnail> makeAvatars(final UniJsonValue header) {
		Variables.requireNonNull(header, "header");
		if (header.contains("banner")) {
			final UniJsonValue c4TabbedHeaderRenderer = header;
			final UniJsonValue avatar = c4TabbedHeaderRenderer.get("avatar");
			final UniJsonValue thumbnails = avatar.get("thumbnails").asArray();
			return __do_avatar_append(thumbnails);
		} else if (header.contains("pageHeaderViewModel")) {
			final UniJsonValue pageHeaderViewModel = header.get("pageHeaderViewModel");
			final UniJsonValue banner = pageHeaderViewModel.get("image");
			final UniJsonValue thumbnails = banner.get("decoratedAvatarViewModel").get("avatar").get("avatarViewModel").get("image").get("sources").asArray();
			return __do_avatar_append(thumbnails);
		} else {
			log.warn("[makeAvatars] No avatars found, um.");
			log.dwarn(header);
			return Lists.of();
		}
	}

	private static List<Thumbnail> __do_avatar_append(final UniJsonValue thumbnails) {
		if (thumbnails.size() == 0) {
			return Lists.of();
		}
		final List<Thumbnail> tb = new ArrayList<Thumbnail>();
		if (thumbnails.size() == 1) {
			final UniJsonValue obj = thumbnails.first();
			tb.add(new Thumbnail(obj.getInt("width"), obj.getInt("height"), obj.getString("url"), "YTE_FLAG_SINGLE"));
		} else {
			for (int idx = 0; idx < thumbnails.size(); idx++) {
				final UniJsonValue obj = thumbnails.get(idx);
				final String flag;
				/* I hope YouTube doesn't change the low -> high resolution ordering... */
				if (idx == 0) {
					flag = ChannelExtractor.MINIMUM_RESOLUTION_FLAG;
				} else if (idx == thumbnails.size() - 1) {
					flag = ChannelExtractor.MAXIMUM_RESOLUTION_FLAG;
				} else {
					flag = null;
				}
				tb.add(new Thumbnail(obj.getInt("width"), obj.getInt("height"), obj.getString("url"), flag));
			}
		}
		return tb;
	}
}
